home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / p4 / p4-1_2c.lha / p4-1.2c / monitors / grid.shmem.c < prev    next >
C/C++ Source or Header  |  1993-05-24  |  6KB  |  265 lines

  1. #include "p4.h"
  2. #define ROWS         200
  3. #define COLUMNS     200
  4. struct globmem {
  5.     double a[ROWS+2][COLUMNS+2];
  6.     double b[ROWS+2][COLUMNS+2];
  7.     int st[ROWS+2], pq[ROWS+1];
  8.     int pqbeg, pqend, goal, nproc, rows, columns;
  9.     p4_askfor_monitor_t MO;
  10.     p4_barrier_monitor_t BA;
  11. } *glob;
  12.  
  13. double avggrid();
  14. double avgbnd();
  15.  
  16. slave()
  17. {
  18.     work('s');
  19. }
  20.  
  21. phi(x,y)            /* The function on the boundary */
  22. int x,y;
  23. {
  24.       return((x * x) - (y * y) + (x * y));   
  25. }
  26.  
  27. main(argc,argv)
  28. int argc;
  29. char **argv;
  30. {
  31.     int i;
  32.     int timestart, timeend;
  33.     p4_usc_time_t start_ustime, end_ustime;
  34.     double avg;
  35.  
  36.     p4_initenv(&argc,argv);
  37.  
  38.     glob = (struct globmem *) p4_shmalloc(sizeof(struct globmem));
  39.  
  40.     p4_askfor_init(&(glob->MO));
  41.     p4_barrier_init(&(glob->BA));
  42.  
  43.     printf("enter number of processes: ");
  44.     scanf("%d",&glob->nproc);
  45.     printf("enter the number of rows: ");
  46.     scanf("%d",&glob->rows);
  47.     printf("enter the number of columns: ");
  48.     scanf("%d",&glob->columns);
  49.     printf("enter the number of iterations: ");
  50.     scanf("%d",&glob->goal);
  51.  
  52.     gridinit(glob->a,glob->rows,glob->columns);
  53.     gridinit(glob->b,glob->rows,glob->columns);
  54.     
  55.     glob->pqbeg = glob->pqend = 0;
  56.     for (i=1; i <= glob->rows; i++)
  57.         queueprob(i);
  58.  
  59.     /* initialize the status vector */
  60.     for (i=0; i < (glob->rows+2); i++)
  61.         glob->st[i] = 0;
  62.  
  63.     printf("\nnproc\tgoal\trows\tcolumns\n");
  64.     printf("%d \t  %d \t  %d \t  %d \n",
  65.        glob->nproc,glob->goal,glob->rows,glob->columns);
  66.     for (i=1; i <= glob->nproc-1; i++) {
  67.         p4_create(slave);
  68.     }
  69.     timestart = p4_clock();
  70.     start_ustime = p4_ustimer();
  71.     work('m');
  72.     end_ustime = p4_ustimer();
  73.     timeend = p4_clock();
  74.     printf("total time %.3f seconds\n",(timeend - timestart)/1000.0);
  75.     printf("total time %.6f seconds\n",(end_ustime-start_ustime)/1000000.0);
  76.  
  77. /* 
  78.     printf("the resulting grid:\n");
  79.     if (glob->goal % 2 == 0)
  80.         printgrid(glob->a,glob->rows,glob->columns);
  81.     else
  82.         printgrid(glob->b,glob->rows,glob->columns);
  83. */
  84.     if (glob->goal % 2 == 0)
  85.         avg = avggrid(glob->a,glob->rows,glob->columns);
  86.     else
  87.         avg = avggrid(glob->b,glob->rows,glob->columns);
  88.     printf("average value of grid = %f\n",avg);
  89.  
  90.     p4_wait_for_end(); 
  91. }
  92.  
  93. /* "m" is the matrix, "r" is the number of rows of data (m[1]-m[r];
  94.    m[0] and m[r+1] are boundaries), and "c" is the number of columns
  95.    of data.
  96. */
  97.  
  98. gridinit(m,r,c)
  99. double m[ROWS+2][COLUMNS+2];
  100. int r, c;
  101. {
  102.     int i, j;
  103.     double bndavg;
  104.     
  105.     for (j=0; j < (c + 2); j++)
  106.     {
  107.         m[0][j] = phi(1,j+1);
  108.         m[r+1][j]= phi(r+2,j+1);
  109.     }
  110.     for (i=1; i < (r + 2); i++)
  111.     {
  112.         m[i][0] = phi(i+1,1);
  113.         m[i][c+1] = phi(i+1,c+2);
  114.     }
  115.     bndavg = avgbnd(m,r,c);
  116.     printf("boundary average = %f\n",bndavg);
  117.  
  118.     /* initialize the interior of the grids to the average over the boundary*/
  119.     for (i=1; i <= r; i++)
  120.         for (j=1; j <= c; j++)
  121.             /* m[i][j] = bndavg; this optimization hinders debugging */
  122.         m[i][j] = 0;
  123. }
  124.  
  125. queueprob(x)
  126. int x;
  127. {
  128.     glob->pq[glob->pqend] = x;
  129.     glob->pqend = (glob->pqend + 1) % (ROWS + 1);
  130. }
  131.  
  132. compute(p,q,r,columns)
  133. double p[ROWS+2][COLUMNS+2];
  134. double q[ROWS+2][COLUMNS+2];
  135. int r;
  136. int columns;
  137. {
  138.     int j;
  139.  
  140.     for (j = 1; j <= columns; j++) 
  141.         q[r][j] = (p[r-1][j] + p[r+1][j] + p[r][j-1] + p[r][j+1]) / 4.0;
  142. }
  143.  
  144. int putprob(r)
  145. int r;
  146. {
  147.     int qprob;
  148.  
  149.     qprob = FALSE;
  150.     glob->st[r]++;
  151.     if (r == 1)
  152.         glob->st[0] = glob->st[r];
  153.  
  154.     else if (r == glob->rows)
  155.         glob->st[glob->rows+1] = glob->st[r];
  156.  
  157.     if (glob->st[r] < glob->goal)
  158.     {
  159.         if ((r > 1) && (glob->st[r-2] >= glob->st[r]) 
  160.             && (glob->st[r-1] == glob->st[r]))
  161.     {
  162.             queueprob(r-1);
  163.             qprob = TRUE;
  164.         }
  165.         if (r < glob->rows && glob->st[r+1] == glob->st[r] 
  166.                && glob->st[r+1] <= glob->st[r+2])
  167.     {
  168.             queueprob(r+1);
  169.             qprob = TRUE;
  170.         }
  171.         if (glob->st[r-1] == glob->st[r] && 
  172.         glob->st[r] == glob->st[r+1])
  173.     {
  174.             queueprob(r);
  175.             qprob = TRUE;
  176.         }
  177.     }
  178.     if (qprob)
  179.         return(1);        /* new problem */
  180.     else
  181.     return(0);        /* no new problem */
  182. }
  183.  
  184. int getprob(v)
  185. int *v;
  186. {
  187.     int rc = 1;
  188.     int *p = (int *) v;
  189.  
  190.     if (glob->pqbeg != glob->pqend) 
  191.     {
  192.     *p = glob->pq[glob->pqbeg];
  193.     glob->pqbeg = (glob->pqbeg+1) % (ROWS + 1); 
  194.     rc = 0;
  195.     }
  196.     return(rc);
  197. }
  198.  
  199. P4VOID reset() 
  200. {
  201. }
  202.  
  203. work(who)            /* main routine for all processes */
  204. char who;
  205. {
  206.     int r,rc,i;
  207.  
  208.     p4_barrier(&(glob->BA),glob->nproc);
  209.  
  210.     rc = p4_askfor(&(glob->MO),glob->nproc,getprob,(P4VOID *)&r,reset);
  211.  
  212.     while (rc == 0) {
  213.     if ((glob->st[r] % 2) == 0)
  214.         compute(glob->a,glob->b,r,glob->columns);
  215.     else 
  216.         compute(glob->b,glob->a,r,glob->columns);
  217.     p4_update(&(glob->MO),putprob,(P4VOID *) r);
  218.     /* postprob(r); */
  219.  
  220.     rc = p4_askfor(&(glob->MO),glob->nproc,getprob,(P4VOID *)&r,reset);
  221.     }
  222. }
  223.  
  224. printgrid(m,r,c)
  225. double m[ROWS+2][COLUMNS+2];
  226. int r,c;
  227. {
  228.     int i,j;
  229.     for (i = 0; i < (r+2); i++)
  230.     for (j = 0; j < (c+2); j++)
  231.         printf("%3d %3d %10.5f\n",i,j,m[i][j]);
  232. }
  233.  
  234. double avggrid(m,r,c)
  235. double m[ROWS+2][COLUMNS+2];
  236. int r,c;
  237. {
  238.     int i,j;
  239.     double avg = 0;
  240.  
  241.     for (i = 0; i < (r+2); i++)
  242.     for (j = 0; j < (c+2); j++)
  243.         avg += m[i][j];
  244.     return(avg/((r+2)*(c+2)));
  245. }
  246.  
  247. double avgbnd(m,r,c)
  248. double m[ROWS+2][COLUMNS+2];
  249. int r,c;
  250. {
  251.     int i,j;
  252.     double avg = 0;
  253.  
  254.     for (i = 0; i < (r+2); i++)
  255.         avg += m[i][0];
  256.     for (i = 0; i < (r+2); i++)
  257.         avg += m[i][c+1];
  258.     for (i = 1; i < (c+1); i++)
  259.         avg += m[0][i];
  260.     for (i = 1; i < (c+1); i++)
  261.         avg += m[r+1][i];
  262.     return(avg/(2*(c+2) + 2*(r+2) - 4)); /* average over boundary */
  263. }
  264.  
  265.